package shiyl.use.any.helloworld.generic;

import java.util.ArrayList;
import java.util.List;

public class Balancer {

    // 模拟一些ILoader
    List<ILoader> loaders = new ArrayList<>() ;
    // 模拟一些ILoader —— 采用方法范型
    List<ILoader<Peer>> loadersF = new ArrayList<>() ;

    Policy policy ;

    public Balancer setPolicy( Policy policy ){
        this.policy = policy ;
        return this ;
    }

    public Balancer regLoader( ILoader loader ){
        this.loaders.add(loader);
        return this ;
    }

    public Balancer regLoaderF( ILoader loader ){
        this.loadersF.add(loader);
        return this ;
    }

    public List<ILoader> getLoaders() {
        return loaders;
    }

    public void setLoaders(List<ILoader> loaders) {
        this.loaders = loaders;
    }

    public List<ILoader<Peer>> getLoadersF() {
        return loadersF;
    }

    public void setLoadersF(List<ILoader<Peer>> loadersF) {
        this.loadersF = loadersF;
    }

    public Policy getPolicy() {
        return policy;
    }

    public Peer select(){
        return policy.selectRandom(this.getLoadersF()) ;
    }

    public ILoader selectF (){
        return policy.selectFirst(this.getLoaders()) ;
    }

    public static final void main(String [] args){

        Balancer balancer = new Balancer() ;
        // loaders中加入的类型是 PeerLoader , 意味这将来取出 Peer
        balancer.regLoader(new PeerLoader().setEndpoint(new Peer("peer0")));
        balancer.regLoader(new PeerLoader().setEndpoint(new Peer("peer1")));
        balancer.regLoader(new PeerLoader().setEndpoint(new Peer("peer2")));
        balancer.regLoader(new PeerLoader().setEndpoint(new Peer("peer3")));

        balancer.regLoaderF(new PeerLoader().setEndpoint(new Peer("peerA")));
        balancer.regLoaderF(new PeerLoader().setEndpoint(new Peer("peerB")));

        Policy p = new Policy() ;
        balancer.setPolicy(p);

        Peer peer1 = p.selectRandom(balancer.getLoadersF());


        //FIXME 没有等号左边的变量指示，不知道getEndpoint() 返回的类型 FIXED 使用范型方法，见 Policy.selectRandom()
        //p.select(loaders).getEndpoint() ;

        //selectRandom是个范型方法，传入的 loadersF 直接指明了类型是Peer，所以可以不用等号左边申明变量
//        System.out.println(p.selectRandom(loadersF).sendProposal("asfsf"));

        System.out.println(balancer.select().sendProposal("asfsf"));


        // 选择一个 Iloader 并指明了 getEndpoiint() 的返回类型为 Peer，但是需要等号左边申明变量
//        ILoader<Peer> selected = p.selectFirst(loaders) ;
        ILoader<Peer > selected = balancer.selectF() ;

        // 返回类型为Peer的对象 等号左边申明变量
        Peer peer = selected.getEndpoint() ;

        // 执行peer的方法
        System.out.println(peer.sendProposal("proposal 11111111"));
    }
}
